package com.istock.test;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

import org.springframework.aop.ClassFilter;
import org.springframework.aop.MethodMatcher;
import org.springframework.aop.Pointcut;
import org.springframework.aop.support.AopUtils;
import org.springframework.core.annotation.AnnotationUtils;

public class ConfigPointCut implements Pointcut{

	private Class<? extends Annotation> annotationType = BusyLogger.class;
	
	@Override
	public ClassFilter getClassFilter() {
		return ClassFilter.TRUE;
	}

	@Override
	public MethodMatcher getMethodMatcher() {
		return new MethodMatcher() {

			@Override
			public boolean matches(Method method, Class<?> targetClass) {
				
				if (matchMethod(method,targetClass)) {
                    return true;
                }
				if (Proxy.isProxyClass(targetClass)) {
					Method specificMethod = AopUtils.getMostSpecificMethod(method, targetClass);
	                return (specificMethod != method && matchMethod(specificMethod,targetClass));
                }
				return false;
			}
			
			private boolean matchMethod(Method method , Class<?> targetClass) {
				Annotation obj = AnnotationUtils.findAnnotation(targetClass, annotationType);
	        	if(obj != null) {
	        		return true;
	        	}else {
	        		obj =  AnnotationUtils.findAnnotation(method, annotationType);
	        		return obj != null;
	        	}
			}

			@Override
			public boolean isRuntime() {
				return true;
			}

			@Override
			public boolean matches(Method method, Class<?> targetClass, Object[] args) {
				return matches(method , targetClass);
			}
			
		};
	}
}
